Skip to content

Fix ActivityLaps import: calculate correct stop_time and preserve zer…#310

Open
lurj7988 wants to merge 1 commit into
tcgoetz:masterfrom
lurj7988:fix/activity-laps-import-stop-time
Open

Fix ActivityLaps import: calculate correct stop_time and preserve zer…#310
lurj7988 wants to merge 1 commit into
tcgoetz:masterfrom
lurj7988:fix/activity-laps-import-stop-time

Conversation

@lurj7988

@lurj7988 lurj7988 commented Apr 1, 2026

Copy link
Copy Markdown

…o values

  • Fix lap data not being imported due to message processing order (hr_zones_timer creates records before lap messages)
  • Calculate stop_time as start_time + elapsed_time instead of using activity timestamp
  • Preserve zero values (distance=0, cycles=0) by changing ignore_zero to False
  • Remove conditional insert check to allow updating existing lap records

…o values

- Fix lap data not being imported due to message processing order (hr_zones_timer creates records before lap messages)
- Calculate stop_time as start_time + elapsed_time instead of using activity timestamp
- Preserve zero values (distance=0, cycles=0) by changing ignore_zero to False
- Remove conditional insert check to allow updating existing lap records

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
tcgoetz added a commit that referenced this pull request May 14, 2026
* 3.6.6 prerelease = false

* Fix multi-sport activity import (#289)

Multi-sport activities (triathlon / brick sessions) are stored by Garmin as
a single FIT file containing multiple `session` messages plus child sessions
for transitions. Previously the importer wrote every session under the bare
parent activity_id, so the last session silently overwrote all the others
and laps/records/HR zones/devices ended up attached to the wrong activity
(or dropped entirely when the hr_zones_timer processing order created empty
rows that blocked the real lap writes).

This change detects multi-sport files by checking `len(fit_file.session) > 1`
and, when detected:

- creates one activity row per session with a suffixed id `<parent>_<n>`
  (e.g. 22638574127_1 ... _5 for swim→T1→run→T2→swim)
- derives each session's `stop_time` from `start_time + total_elapsed_time`
  (Garmin reuses the parent start_time as every child's `timestamp`, which
  would otherwise result in stop_time <= start_time)
- partitions laps by session using each session's `num_laps` and rewrites
  `lap_num` to be session-local (0..N per session), so every child has its
  own contiguous lap sequence
- partitions records (GPS trackpoints) by matching their timestamp against
  each session's time window
- remaps session/lap HR-zone writes to the correct child activity_id
- associates device entries with every child activity

`_write_lap_entry` was also switched to `ActivityLaps.s_insert_or_update` so
lap data correctly coalesces with the hr_zones_timer rows that the generic
message dispatcher creates earlier in the import; the same `stop_time`
correction applies when the file is multi-sport.

Single-session FIT files go through the exact same code path as before.

Extends and supersedes the single-session subset fixed in #310 (same root
cause for `stop_time`, lap-ordering race, and the add-vs-insert-or-update
issue).

Fixes #289

---------

Co-authored-by: Tom Goetz <tcgoetz@gmail.com>
Co-authored-by: Tom Goetz <15090876+tcgoetz@users.noreply.github.com>
@tcgoetz

tcgoetz commented May 15, 2026

Copy link
Copy Markdown
Owner

Please restarted the PR against the develop branch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants